//
// Created by tcj on 2022/2/21.
//

#ifndef __SYLAR_THREAD_H
#define __SYLAR_THREAD_H

//线程的实现
//c++11之前：pthread_xxx
//c++11之后：std::thread,pthread

#include <semaphore.h>
#include "thread"
#include "functional"
#include "memory"
#include "pthread.h"
#include "atomic"
#include "noncopyable.h"


namespace sylar{
//    信号量是指一个整数，提供两个原子操作，p,v操作
//    P操作 (wait操作)：count 减1；如果 count < 0 那么挂起执行线程；
//    V操作 (signal操作)：count 加1；如果 count >= 0 那么唤醒一个执行线程；
    class Semphore : public Noncopyable{
    public:
        //count：信号量大小
        Semphore(uint32_t count=0);
        ~Semphore();
        //获取信号量
        void wait();
        //释放信号量
        void notify();
    private:
        sem_t m_semaphore;
    };


//    局部锁的模板实现
    template<class T>
    struct ScopedLockImpl{
    public:
        ScopedLockImpl(T& mutex):m_mutex(mutex){
            m_mutex.lock();
            m_locked = true;
        }

        ~ScopedLockImpl(){
            unlock();
        }

        void lock(){
            if(!m_locked){
                m_mutex.lock();
                m_locked = true;
            }
        }

        void unlock(){
            if(m_locked){
                m_mutex.unlock();
                m_locked = false;
            }
        }
    private:
        T& m_mutex;
        bool m_locked;
    };


//    局部读锁模板实现
    template<class T>
    struct ReadScopedLockImpl{
    public:
        ReadScopedLockImpl(T& mutex):m_mutex(mutex){
            m_mutex.rdlock();
            m_locked = true;
        }

        ~ReadScopedLockImpl(){
            unlock();
        }

        void lock(){
            if(!m_locked){
                m_mutex.rdlock();
                m_locked = true;
            }
        }

        void unlock(){
            if(m_locked){
                m_mutex.unlock();
                m_locked = false;
            }
        }
    private:
        T& m_mutex;
        bool m_locked;
    };

//    局部写锁模板实现
    template<class T>
    struct WriteScopedLockImpl{
    public:
        WriteScopedLockImpl(T& mutex):m_mutex(mutex){
            m_mutex.wrlock();
            m_locked = true;
        }

        ~WriteScopedLockImpl(){
            unlock();
        }

        void lock(){
            if(!m_locked){
                m_mutex.wrlock();
                m_locked = true;
            }
        }

        void unlock(){
            if(m_locked){
                m_mutex.unlock();
                m_locked = false;
            }
        }
    private:
        T& m_mutex;
        // 是否已经上锁了
        bool m_locked;
    };

//    互斥量
    class Mutex : Noncopyable{
    public:
        typedef ScopedLockImpl<Mutex> Lock;
        Mutex(){
            pthread_mutex_init(&m_mutex, nullptr);
        }
        ~Mutex(){
            pthread_mutex_destroy(&m_mutex);
        }
        void lock(){
            pthread_mutex_lock(&m_mutex);
        }

        void unlock(){
            pthread_mutex_unlock(&m_mutex);
        }

    private:
        pthread_mutex_t m_mutex;
    };

//    空锁：用于调试
    class NUllMutex : Noncopyable{
    public:
        typedef ScopedLockImpl<NUllMutex> Lock;
        NUllMutex(){}
        ~NUllMutex(){}
        void lock(){}
        void unlock(){}
    };

//    读写锁
    class RWMutex :Noncopyable{
    public:
        typedef ReadScopedLockImpl<RWMutex> ReadLock;
        typedef WriteScopedLockImpl<RWMutex> WriteLock;
        RWMutex(){
            pthread_rwlock_init(&m_lock, nullptr);
        }
        ~RWMutex(){
            pthread_rwlock_destroy(&m_lock);
        }

        void rdlock(){
            pthread_rwlock_rdlock(&m_lock);
        }
        void wrlock(){
            pthread_rwlock_wrlock(&m_lock);
        }
        void unlock(){
            pthread_rwlock_unlock(&m_lock);
        }
    private:
        pthread_rwlock_t m_lock;
    };

//    空读写锁(用于调试)
    class NullRWMutex : Noncopyable{
    public:
        typedef ReadScopedLockImpl<NUllMutex> ReadLock;
        typedef WriteScopedLockImpl<NUllMutex> WriteLock;
        NullRWMutex() {}
        ~NullRWMutex(){}

        void rdlock(){}
        void wrlock(){}
        void unlock(){}
    private:
    };

//    自旋锁
    class SpinLock : Noncopyable{
    public:
        typedef ScopedLockImpl<SpinLock> Lock;
        SpinLock(){
            pthread_spin_init(&m_mutex,0);
        }

        ~SpinLock(){
            pthread_spin_destroy(&m_mutex);
        }

        void lock(){
            pthread_spin_lock(&m_mutex);
        }

        void unlock(){
            pthread_spin_unlock(&m_mutex);
        }
    private:
        pthread_spinlock_t m_mutex;
    };

//    原子锁
    class CASLock : Noncopyable{
    public:
        typedef ScopedLockImpl<CASLock> Lock;
        CASLock(){
            m_mutex.clear();
        }
        ~CASLock(){

        }
        void lock(){
            while(std::atomic_flag_test_and_set_explicit(&m_mutex,std::memory_order_acquire));
        }

        void unlock(){
            std::atomic_flag_clear_explicit(&m_mutex,std::memory_order_release);
        }
    private:
        volatile std::atomic_flag m_mutex;
    };

    class Thread{
    public:
//        线程智能指针类型
        typedef std::shared_ptr<Thread> ptr;

//      cb:线程执行函数
        Thread(std::function<void()> cb,const std::string& name);
        ~Thread();

        pid_t getid() const {return m_id;}
//
        const std::string& getName() const {return m_name;}

//        等待线程执行完成
        void join();
//        得到当前线程指针
        static Thread* GetThis();
//        当前线程名称
        static const std::string& GetName();
        static void SetName(const std::string& name);
    private:
        Thread(const Thread&) = delete;
        Thread(const Thread&&) = delete;
        Thread& operator=(const Thread&) = delete;

//        线程执行函数
        static void* run(void* arg);

    private:
        pid_t m_id=-1;
//        线程结构
        pthread_t m_thread=0;
//      function<void()> 表示一个类函数对象的定义
        std::function<void()> m_cb;
//        线程名称  
        std::string m_name;
//        信号量
        Semphore m_semphore;
    };
}



#endif
